#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include <string.h>

#include "wifi_device.h"

#include "lwip/netifapi.h"
#include "lwip/api_shell.h"
#include "lwip/sockets.h"


#include "hi_io.h"
#include "hi_uart.h"
#include "iot_gpio.h"
#include "base_connect.h"

static void PrintLinkedInfo(WifiLinkedInfo *info)
{
    if (!info)
        return;

    static char macAddress[32] = {0};
    unsigned char *mac = info->bssid;
    snprintf(macAddress, sizeof(macAddress), "%02X:%02X:%02X:%02X:%02X:%02X",
             mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
    printf("bssid: %s, rssi: %d, connState: %d, reason: %d, ssid: %s\r\n",
           macAddress, info->rssi, info->connState, info->disconnectedReason, info->ssid);
}

static int g_connected = 0;
static void OnWifiConnectionChanged(int state, WifiLinkedInfo *info)
{
    if (!info)
        return;

    printf("%s %d, state = %d, info = \r\n", __FUNCTION__, __LINE__, state);
    PrintLinkedInfo(info);

    if (state == WIFI_STATE_AVALIABLE)
    {
        g_connected = 1;
    }
    else
    {
        g_connected = 0;
    }
}

static void OnWifiScanStateChanged(int state, int size)
{
    printf("%s %d, state = %X, size = %d\r\n", __FUNCTION__, __LINE__, state, size);
}

void TCP_WIFI_Init(void)
{
    int ret=0;
    WifiErrorCode errCode;
    WifiEvent eventListener = {
        .OnWifiConnectionChanged = OnWifiConnectionChanged,
        .OnWifiScanStateChanged = OnWifiScanStateChanged};
    WifiDeviceConfig apConfig = {};
    int netId = -1;
    osDelay(10);
    errCode = RegisterWifiEvent(&eventListener);
    printf("RegisterWifiEvent: %d\r\n", errCode);

    // setup your AP params
    strcpy(apConfig.ssid, PARAM_HOTSPOT_SSID);
    strcpy(apConfig.preSharedKey, PARAM_HOTSPOT_PSK);
    apConfig.securityType = WIFI_SEC_TYPE_PSK;

    errCode = EnableWifi();
    printf("EnableWifi: %d\r\n", errCode);
    osDelay(10);

    errCode = AddDeviceConfig(&apConfig, &netId);
    printf("AddDeviceConfig: %d\r\n", errCode);

    g_connected = 0;
    errCode = ConnectTo(netId);
    printf("ConnectTo(%d): %d\r\n", netId, errCode);

    while (!g_connected)
    {
        osDelay(10);
    }
    printf("g_connected: %d\r\n", g_connected);
    osDelay(50);

    // 联网业务开始
    struct netif *iface = netifapi_netif_find("wlan0");
    if (iface)
    {
        ip4_addr_t ipaddr;
        ip4_addr_t gateway;
        ip4_addr_t netmask;

        IP4_ADDR(&ipaddr, IPADDR_FIRST, IPADDR_SECOND, IPADDR_THIRD, IPADDR_LAST); /* input your IP for example: 192.168.1.1 */
        IP4_ADDR(&gateway, IPADDR_FIRST, IPADDR_SECOND, IPADDR_THIRD, 1);          /* input your gateway for example: 192.168.1.1 */
        IP4_ADDR(&netmask, 255, 255, 255, 0);        /* input your netmask for example: 255.255.255.0 */
        ret = netifapi_netif_set_addr(iface, &ipaddr, &netmask, &gateway);
        printf("netifapi_netif_set_addr: %d\r\n", ret);

        osDelay(200); // wait DHCP server give me IP
        ip4_addr_t ip = {0};
        ip4_addr_t nm = {0};
        ip4_addr_t gw = {0};
        ret = netifapi_netif_get_addr(iface, &ip, &nm, &gw);
        if (ret == ERR_OK)
        {
            printf("ip = %s\r\n", ip4addr_ntoa(&ip));
        }
        printf("netifapi_netif_get_addr: %d\r\n", ret);
    }
}